package tr.edu.yildiz.ce.dap.appagent.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;

import tr.edu.yildiz.ce.dap.appagent.exception.AgentDeploymentException;
import tr.edu.yildiz.ce.dap.appagent.exception.AgentUninstallException;
import tr.edu.yildiz.ce.dap.appagent.manager.ApplicationManager;
import tr.edu.yildiz.ce.dap.appagent.model.AppDefinition;
import tr.edu.yildiz.ce.dap.appagent.model.Component;
import tr.edu.yildiz.ce.dap.appagent.service.DownloadService;

public class DeploymentUtils {

	public static void installBundle(Component component,String bundleLocation,BundleContext context) throws AgentDeploymentException {
		List<String> actionList = component.getActions().getAction();
		Bundle bundle = null;
		for (String action : actionList) {
			if (action.equals(DeploymentConstants.Action.INSTALL)){
				try {
					bundle = context.installBundle("file:" + bundleLocation);
				} catch (BundleException e) {
					throw new AgentDeploymentException(e);
				}
			}
			if (action.equals(DeploymentConstants.Action.START)){
				try {
					bundle.start();
				} catch (BundleException e) {
					throw new AgentDeploymentException(e);
				}
			}
		}
	}
	
	public static void uninstallApplication(AppDefinition appDefinition,BundleContext context){
		List<Component> cList = appDefinition.getComponentList().getComponent();
		List<Component> reversedList = new ArrayList<Component>();
		for (int i = (cList.size() - 1); i>=0 ; i-- ) {
			reversedList.add(cList.get(i));
		}
		for (Component component : reversedList) {
			try {
				uninstallBundle(component,context);
			} catch (AgentUninstallException e) {
				AppDefinition appDef = getAppDefinitionOfComponent(component);
				System.out.println(appDef.getApp().getName() + "-" +  appDef.getApp().getVersion() + " uses bundle " + component.getName() + "-" + component.getVersion());
			}
		}
	}
	
	public static void uninstallBundle(Component component,BundleContext context) throws AgentUninstallException{
		Bundle[] bundles = context.getBundles();
		try{
			for (Bundle bundle : bundles) {
				if ( (bundle.getHeaders().get("Bundle-Name") != null && bundle.getHeaders().get("Bundle-Name").toString() != null) 
						&& (bundle.getHeaders().get("Bundle-Name") != null && bundle.getHeaders().get("Bundle-Name").toString().equalsIgnoreCase(component.getName()))
						&& (bundle.getHeaders().get("Bundle-Version") != null && bundle.getHeaders().get("Bundle-Version").toString().equalsIgnoreCase(component.getVersion()))){
					bundle.stop();
					bundle.uninstall();
					
				}
			}
		}catch (BundleException e) {
			throw new AgentUninstallException(e);
		}
	}
	
	public static AppDefinition getAppDefinitionOfComponent(Component component){
		List<AppDefinition> appDefinitions = new ArrayList<AppDefinition>();
		try {
			appDefinitions = ApplicationManager.getAllAppDefinition();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		for (AppDefinition appDefinition : appDefinitions) {
			List<Component> componentList = appDefinition.getComponentList().getComponent();
			for (Component c : componentList) {
				if (c.equals(component))
					return appDefinition;
			}
		}
		return null;
	}
	
	public static String downloadBundle(Component component) throws AgentDeploymentException{
		String bundlePath = AgentProperties.getInstance().getBundlePath() + "/" + component.getName()+ "-" +component.getVersion()+ ".jar";
		DownloadService.download(component.getUrl(), bundlePath);
		return bundlePath;
	}
}
